package com.lzq.mq.broker.config;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.lzq.mq.broker.cache.CommonCache;
import com.lzq.mq.broker.model.MqTopicModel;
import com.lzq.mq.broker.utils.FileContentUtil;
import com.lzq.mq.common.constants.BrokerConstants;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.TimeUnit;



/**
 * Topic信息加载器, 用于将加载Topic信息并存储到CommonCache中
 */
@Slf4j
public class MqTopicLoader {
    /**
     * 加载Topic信息
     */
    public void loadProperties() {

        GlobalProperties globalProperties = CommonCache.getGlobalProperties();
        String basePath = globalProperties.getMqHome();
        if (StringUtil.isNullOrEmpty(basePath)) {
            throw new IllegalArgumentException("非法的MQ_HOME");
        }
        String topicJsonFilePath = CommonCache.getGlobalProperties().getBrokerHome() + BrokerConstants.MQ_TOPIC_JSON_PATH;
        // 加载JSON, 读取存在的主题
        String s = FileContentUtil.readFromFile(topicJsonFilePath);
        List<MqTopicModel> topicModelList = JSON.parseArray(s, MqTopicModel.class);
        // 添加映射
        CommonCache.setMqTopicModelList(topicModelList);
        // 配置json加载流程, 封装?
        // 断言 优化判空
    }

    /**
     * 启动主题信息刷盘定时任务
     */
    public void startRefreshMqTopicInfoTask() {
        // 异步线程
        // 每15s将内存中的配置刷新的磁盘中
        // 类似与redis的rdb持久化思路
        CommonThreadPoolConfig.refreshMqTopicExecutor.execute(() -> {
            do {

                try {
                    // 先sleep, 防止初次加载时不必要的刷盘
                    TimeUnit.SECONDS.sleep(BrokerConstants.REFRESH_MQ_TOPIC_TIME_STEP);
                    List<MqTopicModel> topicModelList = CommonCache.getMqTopicModelList();  // 为了配置文件的可读性, 需要以list的形式存储
                    // 刷盘
                    String topicJsonFilePath = CommonCache.getGlobalProperties().getBrokerHome() + BrokerConstants.MQ_TOPIC_JSON_PATH;
                    FileContentUtil.overWriteToFile(topicJsonFilePath, JSON.toJSONString(topicModelList, JSONWriter.Feature.PrettyFormat));
                    //log.info("主题信息刷盘...");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } while (true);
        });
    }
}
